package cn.stylefeng.guns.cloud.workflow.modular.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.cloud.libs.context.auth.LoginContext;
import cn.stylefeng.guns.cloud.libs.mp.page.PageFactory;
import cn.stylefeng.guns.cloud.model.page.PageResult;
import cn.stylefeng.guns.cloud.workflow.api.entity.ActBaseEntity;
import cn.stylefeng.guns.cloud.workflow.core.util.TimeCalcUtil;
import cn.stylefeng.guns.cloud.workflow.modular.model.params.TaskParam;
import cn.stylefeng.guns.cloud.workflow.modular.model.result.DoneTaskResult;
import cn.stylefeng.guns.cloud.workflow.modular.service.ActBaseService;
import cn.stylefeng.guns.cloud.workflow.modular.service.DoneTaskService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 已办任务 服务实现类
 *
 * @Author xuyuxiang
 * @Date 2019/11/17 21:31
 **/
@Service
public class DoneTaskServiceImpl<T extends ActBaseEntity> implements DoneTaskService<T> {

    private final String APPLY_USER_NAME = "applyUserName";

    private final String APPLY_DATE = "applyDate";

    private final String APPLY_USER_ID = "applyUserId";

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ActBaseService actBaseService;

    /**
     * 查询我的已办任务列表
     *
     * @Author xuyuxiang
     * @Date 2019/11/4 16:59
     **/
    public PageResult list(TaskParam taskParam) {

        Page pageContext = this.getPageContext();

        String userIdString = String.valueOf(LoginContext.me().getAccountId());

        taskParam.setAssigneeOrCandidateUserId(userIdString);

        //获取已办任务doneTaskQuery
        HistoricTaskInstanceQuery doneTaskQuery = this.getDoneTaskQuery(taskParam);

        List<HistoricTaskInstance> taskList = doneTaskQuery.listPage((int) pageContext.getSize() * ((int) pageContext.getCurrent() - 1),
                (int) pageContext.getSize());
        long count = doneTaskQuery.count();

        //将已办任务转换成DoneTaskResult
        List<DoneTaskResult> doneTaskResultList = this.copyDoneTaskListInfo(taskList);

        pageContext.setRecords(doneTaskResultList);
        pageContext.setTotal(count);

        return new PageResult(pageContext);
    }

    /**
     * 将HistoricTaskInstance集合转换为TaskModel集合（已办任务）
     *
     * @Author xuyuxiang
     * @Date 2019/11/4 17:14
     **/
    public List<DoneTaskResult> copyDoneTaskListInfo(List<HistoricTaskInstance> taskList) {
        //返回的TaskModel集合
        List<DoneTaskResult> doneTaskResultList = new ArrayList<>();

        for (HistoricTaskInstance historicTaskInstance : taskList) {
            //任务id
            String taskId = historicTaskInstance.getId();
            //任务名称
            String taskName = historicTaskInstance.getName();

            //委托人id
            String taskOwner = historicTaskInstance.getOwner();

            //委托人姓名
            String taskOwnerName = "-";
            if (ObjectUtil.isNotEmpty(taskOwner)) {
                //如果委托人不为空,则展示
                taskOwnerName = actBaseService.getNameByUserId(taskOwner);
            } else {
                taskOwner = "-";
            }

            //获取流程定义id
            String processDefinitionId = historicTaskInstance.getProcessDefinitionId();
            //获取流程定义实例
            ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
            //获取流程名称
            String processDefinitionName = processDefinition.getName();
            //流程实例id
            String processInstanceId = historicTaskInstance.getProcessInstanceId();
            //开始时间
            String startTime = DateUtil.formatDateTime(historicTaskInstance.getStartTime());
            //结束时间
            String endTime = DateUtil.formatDateTime(historicTaskInstance.getEndTime());
            //耗时时间
            String duration = TimeCalcUtil.calc(historicTaskInstance.getDurationInMillis());

            //获取参数列表
            String applyUserId = "-";
            String applyUserName = "-";
            String applyDate = "-";
            List<HistoricVariableInstance> historicVariableInstanceList = historyService
                    .createHistoricVariableInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .list();
            for (HistoricVariableInstance historicVariableInstance : historicVariableInstanceList) {
                //获取参数名称
                String variableName = historicVariableInstance.getVariableName();
                //取出参数
                if (APPLY_USER_ID.equals(variableName)) {
                    //申请人id
                    applyUserId = historicVariableInstance.getValue().toString();
                }
                if (APPLY_USER_NAME.equals(variableName)) {
                    //申请人姓名
                    applyUserName = (String) historicVariableInstance.getValue();
                }
                if (APPLY_DATE.equals(variableName)) {
                    //申请人时间
                    applyDate = (String) historicVariableInstance.getValue();
                }
            }
            //待办任务标题
            String taskTitle = processDefinitionName + "(" + applyUserName + " " + applyDate + ")";

            //创建TaskModel
            DoneTaskResult doneTaskResult = new DoneTaskResult();
            doneTaskResult.setTaskId(taskId);
            doneTaskResult.setProcessDefinitionId(processDefinitionId);
            doneTaskResult.setProcessInstanceId(processInstanceId);
            doneTaskResult.setTaskTitle(taskTitle);
            doneTaskResult.setProcessName(processDefinitionName);
            doneTaskResult.setApplyUserId(applyUserId);
            doneTaskResult.setApplyUserName(applyUserName);
            doneTaskResult.setApplyDate(applyDate);
            doneTaskResult.setApproveProcess(taskName);
            doneTaskResult.setTaskOwnerUserId(taskOwner);
            doneTaskResult.setTaskOwnerName(taskOwnerName);
            doneTaskResult.setStartTime(startTime);
            doneTaskResult.setEndTime(endTime);
            doneTaskResult.setDuration(duration);
            doneTaskResultList.add(doneTaskResult);
        }
        return doneTaskResultList;
    }

    /**
     * 获取已办任务的HistoricTaskInstanceQuery
     *
     * @Author xuyuxiang
     * @Date 2019/11/4 17:05
     **/
    public HistoricTaskInstanceQuery getDoneTaskQuery(TaskParam taskParam) {
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService
                .createHistoricTaskInstanceQuery();

        String processName = taskParam.getProcessName();
        //根据流程名称查询
        if (ObjectUtil.isNotEmpty(processName)) {
            //根据流程名称查询流程定义实例集合
            ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionNameLike("%" + processName + "%");
            List<ProcessDefinition> processDefinitionList = processDefinitionQuery.list();
            //获取流程定义实例的key集合
            Set<String> processKeySet = new HashSet<>();
            for (ProcessDefinition processDefinition : processDefinitionList) {
                String key = processDefinition.getKey();
                processKeySet.add(key);
            }
            List<String> processKeyList = new ArrayList<>(processKeySet);
            historicTaskInstanceQuery.processDefinitionKeyIn(processKeyList);
        }
        //根据申请人查询
        String applyUserId = taskParam.getApplyUserId();
        if (ObjectUtil.isNotEmpty(applyUserId)) {
            //TODO
        }

        String assigneeUserId = taskParam.getAssigneeOrCandidateUserId();

        if (ObjectUtil.isNotEmpty(assigneeUserId)) {
            //根据办理人查询
            historicTaskInstanceQuery.taskAssignee(assigneeUserId);
        }
        //查询当前任务已结束的
        historicTaskInstanceQuery.finished();
        return historicTaskInstanceQuery;
    }


    /**
     * 获取pageContext
     *
     * @Author xuyuxiang
     * @Date 2019/10/25 16:04
     **/
    private Page getPageContext() {
        return PageFactory.defaultPage();
    }
}
